package com.fish.utils;

import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;

public class MemcachedUtil {
	private static Object LOCK = new Object();
	private final static  Log log = LogFactory.getLog(MemcachedUtil.class);
	private Properties properties;
	private MemCachedClient memCachedClient;
	private static int ONE_HOUR=3600;
	
	private static MemcachedUtil instance;
	
	private void init() {
		try {
			properties = new Properties();
			Resource resource=new ClassPathResource("memcached.properties");
			properties.load(resource.getInputStream());
			//,表示配置多个memcache服务
			String[] servers = properties.getProperty("cache.server").split(",");
			SockIOPool pool = SockIOPool.getInstance();
			pool.setServers(servers);
			pool.setFailover(true);
			pool.setInitConn(10);
			pool.setMinConn(5);
			pool.setMaxConn(50);
			pool.setMaintSleep(30);
			pool.setNagle(false);
			pool.setSocketTO(30000);
			//pool.setBufferSize(1024*1024*5);
			pool.setAliveCheck(true);
			pool.initialize(); /* 建立MemcachedClient实例 */
			memCachedClient = new MemCachedClient();
		} catch (IOException e) {
			e.printStackTrace();
		}
		catch (Exception ex) {
			log.error(ex, ex);
		}
	}
	
	private MemcachedUtil(){
		init();
	}
	
	private boolean isCacheEnabled() {
		boolean useCache = false;
		try {
			useCache = Boolean.valueOf(properties.getProperty("cache.enable"));
		} catch (Exception e) {
			useCache = false;
			log.info("Please enable memcached");
		}
		return useCache;
	}
	
	/**
	 * 改用嵌套类静态实始化
	 * @return
	 */
	public static MemcachedUtil getInstance() {
		synchronized(LOCK) {
			if (instance==null) {
				instance=new MemcachedUtil();
			}
		}
		return instance;
	}
	/**
	 * 替换
	 * @param key
	 * @param seconds 过期秒数
	 * @param obj
	 * @return
	 */
	public boolean replace(String key, int seconds, Object obj) {
		if(StringUtils.isEmpty(key)){
			return false;
		}
		if(obj==null){
			return true;
		}
		try{
			if (isCacheEnabled()) {
				log.debug("REPLACE A OBJECT: KEY:" + key + " OBJ:" + obj) ;
				return memCachedClient.replace(key, obj, getDateAfter(seconds));
			}
			return true;
		}catch(Exception e) {
			e.printStackTrace();
			log.error(e, e);
		}
		return false;
	}
	
	/**
	 * 放
	 * @param key
	 * @param seconds 过期秒数
	 * @param obj
	 * @return
	 */
	public boolean set(String key, int seconds, Object obj) {
		return set(key, getDateAfter(seconds), obj);
	}
	
	public boolean set(String key,Date exp,Object obj){
		if(StringUtils.isEmpty(key)){
			return false;
		}
		if(obj==null){
			return true;
		}
		try{
			if (isCacheEnabled()) {
				log.debug("SET A OBJECT: KEY:" + key + " OBJ:" + obj) ;
				return memCachedClient.set(key, obj, exp);
			}
			return true;
		}catch(Exception e) {
			e.printStackTrace();
			log.error(e, e);
		}
		return false;
	}
	
	/**
	 * 放
	 * @param key
	 * @param obj
	 * @return
	 */
	public boolean set(String key, Object obj) {
		return set(key,ONE_HOUR,obj);
	}
	
	/**
	 * 取
	 * @param key
	 * @return
	 */
	public Object get(String key) {
		try{
			if (isCacheEnabled()) {
				Object obj = memCachedClient.get(key);
				log.debug("GET A OBJECT: KEY:" + key + " OBJ:" + obj) ;
				return obj;
			}
		}catch(Exception e) {
			e.printStackTrace();
			log.error(e, e);
		}
		return null;
	}
	
	/**
	 * 取
	 * @param key
	 * @return
	 */
	public boolean remove(String key) {
		if(StringUtils.isEmpty(key)){
			return false;
		}
		try{
			if (isCacheEnabled()) {
				return memCachedClient.delete(key);
			}
		}catch(Exception e) {
			e.printStackTrace();
			log.error(e, e);
		}
		return true;
	}
	
	/**
	 * 刷新缓存
	 */
	public void flushAll(){
		try{
			memCachedClient.flushAll();
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}
	
    /**
     * 获得当前开始活参数分钟的时间日期
    * @Title: getDateAfter
    * @Description:
    * @param
    * @return Date    返回类型
    * @throws
     */
    public static Date getDateAfter(int minute) {
        Calendar cal = Calendar.getInstance();
 		cal.add(Calendar.SECOND, minute);
 		return cal.getTime();
 	}
	
	public static void main(String[] args) {
		Map<String, String> map = new HashMap();
		map.put("Test", "Test");
		for(int i=0;i<1000;i++) {
			String key = RandomFactory.generateMixed(10);
			MemcachedUtil.getInstance().set(key, map);
			System.out.println(key + " : " + MemcachedUtil.getInstance().get(key));
		}
	}
}
